home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 4 / Apprentice-Release4.iso / Source Code / C / Applications / Teapot / TeaGraf.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-11-18  |  4.1 KB  |  143 lines  |  [TEXT/KAHL]

  1. /* Author: David Oster after the 
  2.  * floating point Pascal program by Charles W. Grant
  3.  *
  4.  * Synopsis: The graphic functions for Teapot 3-D
  5.  */
  6. #include "Graf3D.h"
  7. #include "teapot.h"
  8.  
  9. Point3D Pt3ds[1+DUCKCOUNT];
  10.  
  11. /* BlendVector - calculate Bezier spline values for parameter t
  12.  */
  13. static void BlendVector(
  14.     Pt3dPtr d0, Pt3dPtr d1, Pt3dPtr d2, Pt3dPtr d3, Fixed t, Pt3dPtr result){
  15.  
  16.     result->x = 
  17.         FixMul(FixMul(FixMul(d0->x,ONE-t),ONE-t),ONE-t) + 
  18.         FixMul(FixMul(FixMul(FixMul(THREE,d1->x), t),ONE-t),ONE-t) + 
  19.         FixMul(FixMul(FixMul(FixMul(THREE,d2->x), t), t),ONE-t) + 
  20.         FixMul(FixMul(FixMul(d3->x, t), t), t);
  21.     result->y = 
  22.         FixMul(FixMul(FixMul(d0->y,ONE-t),ONE-t),ONE-t) + 
  23.         FixMul(FixMul(FixMul(FixMul(THREE,d1->y), t),ONE-t),ONE-t) + 
  24.         FixMul(FixMul(FixMul(FixMul(THREE,d2->y), t), t),ONE-t) + 
  25.         FixMul(FixMul(FixMul(d3->y, t), t), t);
  26.     result->z = 
  27.         FixMul(FixMul(FixMul(d0->z,ONE-t),ONE-t),ONE-t) + 
  28.         FixMul(FixMul(FixMul(FixMul(THREE,d1->z), t),ONE-t),ONE-t) + 
  29.         FixMul(FixMul(FixMul(FixMul(THREE,d2->z), t), t),ONE-t) + 
  30.         FixMul(FixMul(FixMul(d3->z, t), t), t);
  31. }
  32.  
  33. /* DisplayCurve - find "steps"+1 points on the spline and 
  34.  * draw "steps" line segments
  35.  */
  36. static void DisplayCurve(Pt3dPtr d0, Pt3dPtr d1, Pt3dPtr d2, Pt3dPtr d3, int steps){
  37.     Fixed t;
  38.     Fixed step;
  39.     Fixed loopmax;
  40.     Point3D temp;
  41.     
  42.     step = FixRatio(1, steps);        /*  1/steps */
  43.     t = step;
  44.                                     /* loopmax = 1 + step/2 */
  45.     loopmax = ONE + FixMul(step, HALF);
  46.     MoveTo3D(d0->x, d0->y, d0->z);        /* move to start of spline */
  47.     while(t < loopmax){
  48.         BlendVector(d0, d1, d2, d3, t, &temp);
  49.         LineTo3D(temp.x, temp.y, temp.z);
  50.         t += step;
  51.     }
  52.     OneEvent();    /* let the user choose from the menu */
  53. }
  54.  
  55. /* DisplayPatch - 
  56.  */
  57. void DisplayPatch(Patch patch, int steps){
  58.     Fixed t;
  59.     Fixed step;
  60.     Fixed loopmax;
  61.     Point3D d0, d1, d2, d3;
  62.  
  63.     step = FixRatio(1, steps);    /*  1/steps */
  64.     *((long int *) &t) = 0L;
  65.                                 /* loopmax = 1 + step/2 */
  66.     loopmax = ONE + FixMul(step, HALF);
  67.     
  68.     while(t < loopmax){
  69.                                 /* splines of constant U */
  70.         BlendVector(&Pt3ds[patch[0][0]], &Pt3ds[patch[0][1]], 
  71.                     &Pt3ds[patch[0][2]], &Pt3ds[patch[0][3]], t, &d0);
  72.         BlendVector(&Pt3ds[patch[1][0]], &Pt3ds[patch[1][1]],
  73.                     &Pt3ds[patch[1][2]], &Pt3ds[patch[1][3]], t, &d1);
  74.         BlendVector(&Pt3ds[patch[2][0]], &Pt3ds[patch[2][1]],
  75.                     &Pt3ds[patch[2][2]], &Pt3ds[patch[2][3]], t, &d2);
  76.         BlendVector(&Pt3ds[patch[3][0]], &Pt3ds[patch[3][1]],
  77.                     &Pt3ds[patch[3][2]], &Pt3ds[patch[3][3]], t, &d3);
  78.  
  79.         DisplayCurve(&d0, &d1, &d2, &d3, steps);
  80.                                 /* splines of constant V */
  81.         BlendVector(&Pt3ds[patch[0][0]], &Pt3ds[patch[1][0]],
  82.                     &Pt3ds[patch[2][0]], &Pt3ds[patch[3][0]], t, &d0);
  83.         BlendVector(&Pt3ds[patch[0][1]], &Pt3ds[patch[1][1]],
  84.                     &Pt3ds[patch[2][1]], &Pt3ds[patch[3][1]], t, &d1);
  85.         BlendVector(&Pt3ds[patch[0][2]], &Pt3ds[patch[1][2]],
  86.                     &Pt3ds[patch[2][2]], &Pt3ds[patch[3][2]], t, &d2);
  87.         BlendVector(&Pt3ds[patch[0][3]], &Pt3ds[patch[1][3]], 
  88.                     &Pt3ds[patch[2][3]], &Pt3ds[patch[3][3]], t, &d3);
  89.         DisplayCurve(&d0, &d1, &d2, &d3, steps);
  90.  
  91.         t += step;
  92.     } 
  93. }
  94.  
  95. /* DisplayPatches - steps tells how much to divide up patches
  96.  */
  97. void DisplayPatches(int steps){
  98.     int i;
  99.  
  100.     for(i=0; i< PATCHCOUNT; i++){
  101.         DisplayPatch(patches[i], steps);
  102.     }
  103. }
  104.  
  105. /* FloatToFixed - convert from float to fix
  106.  * note this routine doesn't work in general.
  107.  * it works here only because abs(fl) is always < 30
  108.  * On the new roms X2Fix(float) does what you want
  109.  */
  110. static Fixed FloatToFixed(float fl){
  111.     return FixRatio( (int) (fl * 1000.0),1000);
  112. }
  113.  
  114. /* FloatsToFixeds - convert an array from one type to the other
  115.  */
  116. void FloatsToFixeds(register float *fl, Fixed *fi, int n){
  117.     while(n-- > 0){
  118.         *fi++ = FloatToFixed(*fl++);
  119.     }
  120. }
  121.  
  122. /*
  123. note: (Fixed) 8 is a number very near zero.
  124.  */
  125. void BaseGrid(void){
  126.     int i;
  127.     Pattern savePattern;
  128.  
  129.     BlockMove((Ptr) &thePort->pnPat, (Ptr) &savePattern, sizeof(Pattern));
  130.     PenPat(&dkGray);
  131.     PenSize(2,2);
  132.     for(i = -10;i<=10;i++){
  133.         MoveTo3D(FixRatio(i, 4), FixRatio(-10, 4), -(Fixed) 8);
  134.         LineTo3D(FixRatio(i, 4), FixRatio(10, 4), -(Fixed) 8);
  135.     }
  136.     for(i = -10;i<=10;i++){
  137.         MoveTo3D(FixRatio(-10, 4), FixRatio(i, 4), -(Fixed) 8);
  138.         LineTo3D(FixRatio(10, 4), FixRatio(i, 4), -(Fixed) 8);
  139.     }
  140.     PenSize(1,1);
  141.     PenPat(&savePattern);
  142. }
  143.